mod decode;
mod encode;


use std::{
    collections::{HashMap, HashSet},
    ops::{Deref},
   };

use anyhow::Result;
use bytes::BytesMut;
use thiserror::Error;
//use bytes::{Bytes, BytesMut, Buf, BufMut};
use enum_dispatch::enum_dispatch;


#[enum_dispatch]
pub trait RespEncode {
    fn encode(self) -> Vec<u8>;
}

pub trait RespDecode : Sized{
    fn decode(buf: &mut BytesMut) -> Result<Self,RespError>;
}

// impl RespDecode for BytesMut {
//     fn decode(buf: Self) -> Result<RespFrame, String> {
//         todo!()
//     }
// }


#[derive(Error, Debug)]
pub enum RespError {
    #[error("Invalid frame :{0}")]
    InvalidFrame(String),
    #[error("Invalid frame type:{0}")]
    InvalidFrameType(String),
    
    #[error("Invalid frame length:{0}")]
    InvalidFrameLenght(isize),

    
    #[error("Frame is not complete")]
    NotComplete(String),
}

#[enum_dispatch(RespEncode)]
pub enum RespFrame {
    SimpleString(SimpleString),
    Error(SimpleError),
    Integer(i64),
    BulkString(BulkString),
    NullBulkString(RespNullBulkString),
    Array(RespArray),
    Null(RespNull),
    NullArray(RespNullArray),
    Boolean(bool),
    Double(f64),
    //BigNumber(i64),  // bignumber 在rust 下没有很好的支持， 所以暂不支持
    Map(RespMap),
    Set(RespSet),
}

pub struct SimpleString(String);
pub struct SimpleError(String);

pub struct BulkString(Vec<u8>);

pub struct RespNull;
pub struct RespNullArray;

pub struct RespNullBulkString;

pub struct  RespMap(HashMap<String,RespFrame>);

pub struct RespArray(Vec<RespFrame>);

pub struct RespSet(HashSet<RespFrame>);

impl Deref for SimpleString{
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


impl Deref for SimpleError {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


impl Deref for BulkString {
    type Target = Vec<u8>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Deref for RespArray {
    type Target = Vec<RespFrame>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}


impl Deref for RespMap{
    type Target = HashMap<String,RespFrame>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Deref for RespSet {
    type Target = HashSet<RespFrame>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl SimpleString {
    pub fn new(s: impl Into<String>) -> Self {
        SimpleString(s.into())
    }
}

impl SimpleError {
    pub fn new(s: impl Into<String>) -> Self {
        SimpleError(s.into())
    }
}

impl BulkString {
    pub fn new(s: impl Into<Vec<u8>>) -> Self {
        BulkString(s.into())
    }
}

impl RespArray {
    pub fn new(s: impl Into<Vec<RespFrame>>) -> Self {
        RespArray(s.into())
    }
}


impl RespMap {
    pub fn new(s: impl Into<HashMap<String,RespFrame>>) -> Self {
        RespMap(s.into())
    }
}


impl RespSet{
    pub fn new(s: impl Into<HashSet<RespFrame>>) -> Self {
        RespSet(s.into())
    } 
}




/* 下面这些， 已被  #[enum_dispatch(RespEncode)]  实现好了， 不用自己写了   */
// impl From<SimpleString> for RespFrame {
//     fn from(value: SimpleString) -> Self {
//         RespFrame::SimpleString(value)
//     }
// }

// impl From<SimpleError> for RespFrame {
//     fn from(value: SimpleError) -> Self {
//         RespFrame::Error(value)
//     }
// }


// impl From<i64> for  RespFrame {
//     fn from(s: i64) -> Self {
//         RespFrame::Integer(s)
//     }
// }

// impl From<BulkString> for  RespFrame {
//     fn from(s: BulkString) -> Self {
//         RespFrame::BulkString(s)
//     }
// }

// impl From<RespNullBulkString> for  RespFrame {
//     fn from(s: RespNullBulkString) -> Self {
//         RespFrame::NullBulkString(s)
//     }
// }


// impl From<RespArray> for  RespFrame {
//     fn from(s: RespArray) -> Self {
//         RespFrame::Array(s)
//     }
// }

// impl From<RespNullArray> for  RespFrame {
//     fn from(s: RespNullArray) -> Self {
//         RespFrame::NullArray(s)
//     }
// }

// impl From<RespNull> for  RespFrame {
//     fn from(s: RespNull) -> Self {
//         RespFrame::Null(s)
//     }
// }


// impl From<bool> for  RespFrame {
//     fn from(s: bool) -> Self {
//         RespFrame::Boolean(s)
//     }
// }

// impl From<f64> for  RespFrame {
//     fn from(s: f64) -> Self {
//         RespFrame::Double(s)
//     }
// }

// impl From<RespMap> for  RespFrame {
//     fn from(s: RespMap) -> Self {
//         RespFrame::Map(s)
//     }
// }

// impl From<RespSet> for  RespFrame {
//     fn from(s: RespSet) -> Self {
//         RespFrame::Set(s)
//     }
// }